package com.test2.opencv;


import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio;


public class TestFace {

    // 初始化人脸探测器
    static CascadeClassifier faceDetector;

    static {
        // 加载OpenCV本地库
        nu.pattern.OpenCV.loadShared();
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        // 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器，文件位于opencv安装目录中
        faceDetector = new CascadeClassifier("d:\\haarcascade_frontalface_alt.xml");
    }

    public static void main(String[] args) throws Exception {
        cameraFaceRecognition();
        // 终止当前运行的 Java 虚拟机。
        System.exit(0);
    }

    /**
     * 摄像头实时人脸识别
     *
     * @throws Exception
     */
    public static void cameraFaceRecognition() throws Exception {
        // 打开摄像头获取视频流，0 打开默认摄像头
        VideoCapture videoCapture = new VideoCapture(0);
        // 检查是否支持摄像头  true：代表摄像头可以打开  false：不可以打开
        System.out.println(videoCapture.isOpened());
        // 获取摄像头高度
        int height = (int) videoCapture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
        // 获取摄像头宽度
        int width = (int) videoCapture.get(Videoio.CAP_PROP_FRAME_WIDTH);
        if (height == 0 || width == 0) {
            throw new Exception("摄像头不存在");
        }

        Mat video = new Mat();
        int index = 0;
        if (videoCapture.isOpened()) {
            while (true) {
                videoCapture.read(video);
                HighGui.imshow("实时人脸识别", getFace(video));
                // 键盘输入
                index = HighGui.waitKey(50);
                // 是Esc则退出，比强制退出好
                if (index == 27) {
                    // 写入人脸
                    Imgcodecs.imwrite("D:\\" + "face11.png", video);
                    videoCapture.release();
                    return;
                }
            }
        }
    }

    /**
     * 从视频帧中识别人脸
     *
     * @param image 待处理Mat图片，即视频中的某一帧
     * @return 处理后的图片
     */
    public static Mat getFace(Mat image) {
        MatOfRect face = new MatOfRect();
        // 检测输入图像中不同大小的对象。检测到的对象作为矩形列表返回。
        faceDetector.detectMultiScale(image, face);
        Rect[] rects = face.toArray();
        System.out.println("识别人脸个数： " + rects.length);

        if (rects != null && rects.length >= 1) {
            // 为每张识别到的人脸画一个圈
            for (int i = 0; i < rects.length; i++) {
                // 绘制一个简单的、粗的或填充的直角矩形
                Imgproc.rectangle(image, new Point(rects[i].x, rects[i].y), new Point(rects[i].x + rects[i].width, rects[i].y + rects[i].height), new Scalar(0, 255, 0));
                // 绘制一个文本字符串,放在识别人脸框上
                Imgproc.putText(image, "test", new Point(rects[i].x, rects[i].y), Imgproc.FONT_HERSHEY_SCRIPT_SIMPLEX, 1.0, new Scalar(0, 255, 0), 1, Imgproc.LINE_AA, false);
            }
        }
        return image;
    }

}
